package com.hengpeng.itfin.domain.partner.chinapnr;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.hengpeng.common.exception.ServiceResult;
import com.hengpeng.common.exception.SystemException;
import com.hengpeng.common.util.MD5;
import com.hengpeng.common.util.MoneyUtil;
import com.hengpeng.common.util.ObjectHelper;
import com.hengpeng.common.util.StringHelper;
import com.hengpeng.common.util.WebClientUtil;
import com.hengpeng.itfin.constants.MSConstants;
import com.hengpeng.itfin.domain.partner.AbstractPartnerProcessor;
import com.hengpeng.itfin.domain.partner.chinapnr.util.KeyTool;
import com.hengpeng.itfin.service.ServiceFactory;
import com.hengpeng.itfin.tools.JsonUtils;
import com.hengpeng.itfin.tools.StringUtils;
import com.hengpeng.itfinbase.constants.RespCodeConstants;
import com.hengpeng.itfinbase.en.AuditStat;
import com.hengpeng.itfinbase.message.ResponseMessage;
import com.hengpeng.itfinbase.message.partner.AddBidInfoRequest;
import com.hengpeng.itfinbase.message.partner.AddBidInfoResponse;
import com.hengpeng.itfinbase.message.partner.BindCardRequest;
import com.hengpeng.itfinbase.message.partner.BindCardResponse;
import com.hengpeng.itfinbase.message.partner.CashRequestMsg;
import com.hengpeng.itfinbase.message.partner.CashResponseMsg;
import com.hengpeng.itfinbase.message.partner.CorpOpenRequestMsg;
import com.hengpeng.itfinbase.message.partner.CorpOpenResponseMsg;
import com.hengpeng.itfinbase.message.partner.CorpRegisterQueryRequest;
import com.hengpeng.itfinbase.message.partner.CorpRegisterQueryResponse;
import com.hengpeng.itfinbase.message.partner.CreditAssignRequest;
import com.hengpeng.itfinbase.message.partner.CreditAssignResponse;
import com.hengpeng.itfinbase.message.partner.DrawReconciliationRequestMsg;
import com.hengpeng.itfinbase.message.partner.DrawReconciliationResponseMsg;
import com.hengpeng.itfinbase.message.partner.InvestInfoRequestMsg;
import com.hengpeng.itfinbase.message.partner.InvestInfoResponseMsg;
import com.hengpeng.itfinbase.message.partner.LoansRequest;
import com.hengpeng.itfinbase.message.partner.LoansResponse;
import com.hengpeng.itfinbase.message.partner.ModifyRequest;
import com.hengpeng.itfinbase.message.partner.NotifyRequestMsg;
import com.hengpeng.itfinbase.message.partner.NotifyResponseMsg;
import com.hengpeng.itfinbase.message.partner.OpenRequestMsg;
import com.hengpeng.itfinbase.message.partner.OpenResponseMsg;
import com.hengpeng.itfinbase.message.partner.PayRequestMsg;
import com.hengpeng.itfinbase.message.partner.PayResponseMsg;
import com.hengpeng.itfinbase.message.partner.QueryAcctsRequestMsg;
import com.hengpeng.itfinbase.message.partner.QueryAcctsResponseMsg;
import com.hengpeng.itfinbase.message.partner.QueryBalanceRequest;
import com.hengpeng.itfinbase.message.partner.QueryBalanceResponse;
import com.hengpeng.itfinbase.message.partner.QueryCardInfoRequestMsg;
import com.hengpeng.itfinbase.message.partner.QueryCardInfoResponseMsg;
import com.hengpeng.itfinbase.message.partner.QueryTransDetailRequest;
import com.hengpeng.itfinbase.message.partner.QueryTransDetailResponse;
import com.hengpeng.itfinbase.message.partner.QueryTransStatRequest;
import com.hengpeng.itfinbase.message.partner.QueryTransStatResponse;
import com.hengpeng.itfinbase.message.partner.ReconciliationRequestMsg;
import com.hengpeng.itfinbase.message.partner.ReconciliationResponseMsg;
import com.hengpeng.itfinbase.message.partner.RepaymentRequestMsg;
import com.hengpeng.itfinbase.message.partner.RepaymentResponseMsg;
import com.hengpeng.itfinbase.message.partner.RepaymentResponseMsg.RepaymentResponseErrorMsg;
import com.hengpeng.itfinbase.message.partner.SaveReconciliationRequestMsg;
import com.hengpeng.itfinbase.message.partner.SaveReconciliationResponseMsg;
import com.hengpeng.itfinbase.message.partner.TenderCancleRequest;
import com.hengpeng.itfinbase.message.partner.TenderCancleResponse;
import com.hengpeng.itfinbase.message.partner.TransferRequest;
import com.hengpeng.itfinbase.message.partner.TransferResponse;
import com.hengpeng.itfinbase.message.partner.TrfReconciliationRequestMsg;
import com.hengpeng.itfinbase.message.partner.TrfReconciliationResponseMsg;
import com.hengpeng.itfinbase.message.partner.UsrUnFreezeRequest;
import com.hengpeng.itfinbase.message.partner.UsrUnFreezeResponse;
import com.hengpeng.itfinbase.persist.Partner;
import com.hengpeng.itfinbase.persist.Payment;
import com.hengpeng.itfinbase.persist.SystemLog.LogType;
import com.hengpeng.itfinbase.persist.Transfer;
import com.hengpeng.itfinbase.persist.UserInfo;
import com.ibm.icu.math.BigDecimal;

public class ChinapnrProcessorImpl extends AbstractPartnerProcessor {
    // 开户返回签名校验数据key列表
    private static final Log logger = LogFactory.getLog(ChinapnrProcessorImpl.class);

    // 汇付应答签数据key列表
    public static final String[] VERIFY_KYES_USER_REGISTER = { "CmdId", "RespCode", "MerCustId", "UsrId", "UsrCustId",
            "BgRetUrl", "TrxId", "RetUrl", "MerPriv" };

    // 商户开户返回签名校验数据key列表
    public static final String[] VERIFY_KYES_CORPUSER_REGISTER = { "CmdId", "RespCode", "MerCustId", "UsrId",
            "UsrName", "UsrCustId", "AuditStat", "TrxId", "OpenBankId", "CardId", "BgRetUrl", "RespExt" };

    // 绑卡返回签名校验数据key列表
    public static final String[] VERIFY_KEYS_BINDCARD = { "CmdId", "RespCode", "MerCustId", "OpenAcctId", "OpenBankId",
            "UsrCustId", "TrxId", "BgRetUrl", "MerPriv" };

    // 充值返回签名校验数据key列表
    public static final String[] VERIFY_KEYS_NET_SAVE = { "CmdId", "RespCode", "MerCustId", "UsrCustId", "OrdId",
            "OrdDate", "TransAmt", "TrxId", "RetUrl", "BgRetUrl", "MerPriv" };

    // 取现返回签名校验数据key列表
    public static final String[] VERIFY_KEYS_CASH_RETURN = { "CmdId", "RespCode", "MerCustId", "OrdId", "UsrCustId",
            "TransAmt", "OpenAcctId", "OpenBankId", "FeeAmt", "FeeCustId", "FeeAcctId", "ServFee", "ServFeeAcctId",
            "RetUrl", "BgRetUrl", "MerPriv", "RespExt" };

    // 取现对账签名校验数据key列表
    public static final String[] VERIFY_KEYS_CASH_RECONCIL = { "RespType", "RespCode", "MerCustId", "OrdId",
            "UsrCustId", "TransAmt", "OpenAcctId", "OpenBankId", "RetUrl", "BgRetUrl", "MerPriv", "RespExt" };

    // 转账
    public static final String[] VERIFY_KEYS_TRANSFER = { "CmdId", "RespCode", "OrdId", "OutCustId", "OutAcctId",
            "TransAmt", "InCustId", "InAcctId", "RetUrl", "BgRetUrl", "MerPriv" };

    public static final String[] VERIFY_KEYS_QUERY_ACCT = { "CmdId", "RespCode", "MerCustId" };

    /**
     * 企业开户状态查询
     */
    public static final String[] VERIFY_KEYS_QUERY_CORPREGISTER = { "CmdId", "RespCode", "MerCustId", "UsrCustId",
            "UsrId", "AuditStat", "BusiCode", "RespExt" };

    /**
     * 批量还款返回参数
     */
    public static final String[] VERIFY_KEYS_BATCH_REPAYMENT = { "CmdId", "RespCode", "MerCustId", "OutCustId",
            "OutAcctId", "BatchId", "MerOrdDate", "BgRetUrl", "MerPriv", "SucNum", "FailNum", "ErrMsg", "ProId",
            "ReqExt" };

    /**
     * 还款返回参数
     */
    public static final String[] VERIFY_KEYS_REPAYMENT = { "CmdId", "RespCode", "MerCustId", "OrdId", "OrdDate",
            "OutCustId", "SubOrdId", "SubOrdDate", "OutAcctId", "TransAmt", "Fee", "InCustId", "InAcctId",
            "FeeObjFlag", "BgRetUrl", "MerPriv", "RespExt" };

    /**
     * 后台余额查询返回参数
     */
    public static final String[] VERIFY_KEYS__QUERYBALANCEBG = { "CmdId", "RespCode", "MerCustId", "UsrCustId",
            "AvlBal", "AcctBal", "FrzBal" };

    /**
     * 银行卡查询返回参数验签
     */
    public static final String[] VERIFY_KEYS__QUERYCARDINFO = { "CmdId", "RespCode", "MerCustId", "UsrCustId", "CardId" };

    /**
     * 放款还款对账返回参数验签
     */
    public static final String[] VERIFY_KEYS__RECONCILIATION = { "CmdId", "RespCode", "MerCustId", "BeginDate",
            "EndDate", "PageNum", "PageSize", "TotalItems", "QueryTransType" };

    /**
     * 商户扣款对账参数验签
     */
    public static final String[] VERIFY_KEYS__TRFRECONCILIATION = { "CmdId", "RespCode", "MerCustId", "BeginDate",
            "EndDate", "PageNum", "PageSize", "TotalItems" };

    /**
     * 充值对账参数验签
     */
    public static final String[] VERIFY_KEYS__SAVERECONCILIATION = { "CmdId", "RespCode", "MerCustId", "BeginDate",
            "EndDate", "PageNum", "PageSize", "TotalItems" };

    /**
     * 取现对象验签参数
     */
    public static final String[] VERIFY_KEYS__CASHRECONCILIATION = { "CmdId", "RespCode", "MerCustId", "BeginDate",
            "EndDate", "PageNum", "PageSize", "TotalItems", "FeeObj" };

    /**
     * 债权转让验签
     */
    public static final String[] VERIFY_KEYS_CREDITASSIGN = { "CmdId", "RespCode", "MerCustId", "SellCustId",
            "CreditAmt", "CreditDealAmt", "Fee", "BuyCustId", "OrdId", "OrdDate", "RetUrl", "BgRetUrl", "MerPriv",
            "RespExt" };

    /**
     * 交易查询返回参数验签
     */
    public static final String[] VERIFY_KEYS_QueryTransStat = { "CmdId", "RespCode", "MerCustId", "OrdId", "OrdDate",
            "QueryTransType", "TransStat" };
    /**
     * 冻结解冻交易查询返回参数验签
     */
    public static final String[] VERIY_KEYS_FREEUNFREE = { "CmdId", "RespCode", "MerCustId", "OrdId", "OrdDate",
            "QueryTransType", "TransStat", "TransAmt", "TrxId" };

    /**
     * 投资返回参数
     */
    public static final String[] VERIFY_KEYS_INITIATIVETENDER = { "CmdId", "RespCode", "MerCustId", "OrdId", "OrdDate",
            "TransAmt", "UsrCustId", "TrxId", "IsFreeze", "FreezeOrdId", "FreezeTrxId", "RetUrl", "BgRetUrl",
            "MerPriv", "RespExt" };

    private static final String CONFIG_VERSION10 = "version10";

    private static final String CONFIG_VERSION20 = "version20";

    private static final String CONFIG_MAXTENDERRATE = "MaxTenderRate";

    public String version10;

    private String version20;

    private String max_Tender_Rate;

    private KeyTool keyTool;

    private String charSet = "utf-8";

    private String returnNotifyParamValuePre = "RECV_ORD_ID_";

    public ChinapnrProcessorImpl(ServiceFactory serviceFactory, Partner partner) {
        super(serviceFactory, partner);
        version10 = extConfigs.get(CONFIG_VERSION10);
        version20 = extConfigs.get(CONFIG_VERSION20);
        max_Tender_Rate = extConfigs.get(CONFIG_MAXTENDERRATE);
        keyTool = new KeyTool(partner.getPrivateKey(), partner.getPublicKey());
    }

    @Override
    public ResponseMessage packageOpenRequest(OpenRequestMsg request) {
        String idType = "00";// 固定只能用身份证
        String userId = StringUtils.format(request.getUserId(), 6);
        StringLinker sl = new StringLinker();
        String realName = gbEncoding(request.getRealName());
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getBgRetUrl()).append(request.getRetUrl()).append(userId).append(realName)
                .append(idType).append(request.getCardNumber()).append(request.getMobile())
                .append(request.getMerPriv());
        if (request.getPageType() != null && request.getPageType().equals("2")) {
            sl.append("2");
        }
        String checkValue = keyTool.signMessage(sl.toString());// 签名

        ParamHash pl = new ParamHash();
        pl.append("Version", version10).append("CmdId", request.getPartnerTransType().getType())
                .append("MerCustId", partner.getMerchantId()).append("BgRetUrl", request.getBgRetUrl())
                .append("UsrId", userId).append("ChkValue", checkValue).append("RetUrl", request.getRetUrl())
                .append("UsrName", realName).append("IdType", idType).append("IdNo", request.getCardNumber())
                .append("UsrMp", request.getMobile()).append("MerPriv", request.getMerPriv());
        if (request.getPageType() != null && request.getPageType().equals("2")) {
            pl.append("PageType", "2");
        }
        pl.append("CharSet", charSet);
        String htmlString = null;

        htmlString = WebClientUtil.autoSubmitHtmlForm(MSConstants.UTF8, request.getPartnerTransType().getText(),
                partner.getGateWayUrl(), pl.getParams(), "POST");
        logger.info(request.getPartnerTransType().getType() + "生成的表单内容为：\n" + htmlString);

        ResponseMessage response = new ResponseMessage();
        response.setOrderFormContent(htmlString);
        response.setRespCode(RespCodeConstants.CommonCode.TRANS_SUC);
        return response;
    }

    public static String gbEncoding(String gbString) {
        String newString = null;
        try {
            newString = new String(gbString.getBytes(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return newString;
    }

    @Override
    public NotifyResponseMsg openNotify(NotifyRequestMsg request) {
        NotifyResponseMsg response = new NotifyResponseMsg();
        if (verifySign(request.getParameter(), VERIFY_KYES_USER_REGISTER)) {
            OpenResponseMsg openRes = null;
            openRes = new OpenResponseMsg();
            openRes.setRespCode(request.getParameter().get("RespCode"));
            openRes.setRespDesc(request.getParameter().get("RespDesc"));
            openRes.setMerPriv(request.getParameter().get("MerPriv"));
            openRes.setIdNo(request.getParameter().get("IdNo"));
            openRes.setUsrCustId(request.getParameter().get("UsrCustId"));
            openRes.setUsrMp(request.getParameter().get("UsrMp"));
            openRes.setUsrEmail(request.getParameter().get("UsrEmail"));
            openRes.setUsrName(request.getParameter().get("UsrName"));
            openRes.setTrxId(request.getParameter().get("TrxId"));
            if (openRes.getRespCode().equals(RespCodeConstants.CommonCode.TRANS_SUC)) {
                response.setRespCode(openRes.getRespCode());
                response.setRespDesc(openRes.getRespDesc());
                ServiceResult<UserInfo> result = serviceFactory.getUserInfoService().dealOpenResult(openRes);
                if (result.getIsSuccess()) {
                    response.setReturnNotifyParamValue(returnNotifyParamValuePre + openRes.getTrxId());
                    response.setReturnObject(result.getReturnValue());
                } else {
                    response.setReturnNotifyParamValue(returnNotifyParamValuePre + openRes.getTrxId());
                }
            } else {
                response.setRespCode(openRes.getRespCode());
                response.setRespDesc(openRes.getRespDesc());
            }
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    /**
     * <pre>
     * 验证签名
     * </pre>
     * 
     * @param param
     * @param verifyList
     * @return
     */
    public boolean verifySign(Map<String, String> param, String[] verifyList) {
        try {
            if (param.isEmpty() || verifyList == null) {
                return false;
            }
            String plaintStr = "";
            for (String i : verifyList) {
                plaintStr += (param.get(i) == null ? "" : param.get(i));
            }
            return keyTool.verifySign(URLDecoder.decode(plaintStr, "utf-8"), (String) param.get("ChkValue"));
        } catch (Exception e) {
            throw new SystemException(e);
        }
    }

    /**
     * <pre>
     * 发送http请求
     * </pre>
     * 
     * @param params
     * @param url
     * @return
     */
    public static String httpRequest(List<NameValuePair> params, String url) {
        String respStr = "";
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost post = new HttpPost(url);
            post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));

            HttpResponse response = httpclient.execute(post);
            HttpEntity entity = response.getEntity();
            respStr = EntityUtils.toString(entity);
            EntityUtils.consume(entity);
        } catch (IOException e) {
            e.printStackTrace();
            logger.error(e);
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return respStr;
    }

    @Override
    public ResponseMessage packageCorpOpenRequest(CorpOpenRequestMsg request) {
        // 签名： Version + CmdId + MerCustId + UsrId + UsrName +InstuCode
        // +BusiCode + TaxCode + MerPriv +GuarType +
        // BgRetUrl+ ReqExt
        String userId = StringUtils.format(request.getUserId(), 6);
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(userId).append(request.getRealName()).append(request.getInstuCode())
                .append(request.getBusiCode()).append(request.getTaxCode()).append(request.getMerPriv())
                .append(request.getGuarType()).append(request.getBgRetUrl());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        ParamHash pl = new ParamHash();
        pl.append("Version", version10).append("CmdId", request.getPartnerTransType().getType())
                .append("MerCustId", partner.getMerchantId()).append("BgRetUrl", request.getBgRetUrl())
                .append("UsrId", userId).append("ChkValue", checkValue).append("UsrName", request.getRealName())
                .append("InstuCode", request.getInstuCode()).append("BusiCode", request.getBusiCode())
                .append("TaxCode", request.getTaxCode()).append("GuarType", request.getGuarType())
                .append("MerPriv", request.getMerPriv()).append("CharSet", charSet);
        String htmlString = null;

        htmlString = WebClientUtil.autoSubmitHtmlForm(MSConstants.UTF8, request.getPartnerTransType().getText(),
                partner.getGateWayUrl(), pl.getParams(), "POST");
        logger.info(request.getPartnerTransType().getType() + "生成的表单内容为：\n" + htmlString);

        ResponseMessage response = new ResponseMessage();
        response.setOrderFormContent(htmlString);
        response.setRespCode(RespCodeConstants.CommonCode.TRANS_SUC);
        return response;
    }

    @Override
    public NotifyResponseMsg corpOpenNotify(NotifyRequestMsg request) {
        NotifyResponseMsg response = new NotifyResponseMsg();
        if (verifySign(request.getParameter(), VERIFY_KYES_CORPUSER_REGISTER)) {
            CorpOpenResponseMsg openRes = null;
            openRes = new CorpOpenResponseMsg();
            openRes.setRespCode(request.getParameter().get("RespCode"));
            openRes.setRespDesc(request.getParameter().get("RespDesc"));
            openRes.setMerPriv(request.getParameter().get("MerPriv"));
            openRes.setUsrCustId(request.getParameter().get("UsrCustId"));
            openRes.setAuditStat(request.getParameter().get("AuditStat"));
            openRes.setAuditDesc(request.getParameter().get("AuditDesc"));
            openRes.setTrxId(request.getParameter().get("TrxId"));
            openRes.setUsrName(request.getParameter().get("UsrName"));
            openRes.setCardId(request.getParameter().get("CardId"));
            openRes.setOpenBankId(request.getParameter().get("OpenBankId"));

            if (openRes.getRespCode().equals(RespCodeConstants.CommonCode.TRANS_SUC)) {
                response.setRespCode(openRes.getRespCode());
                response.setRespDesc(openRes.getRespDesc());
                ServiceResult<UserInfo> result = serviceFactory.getUserInfoService().dealCorpOpenResult(openRes);
                if (result.getIsSuccess()) {
                    response.setReturnNotifyParamValue(returnNotifyParamValuePre + openRes.getTrxId());
                    response.setReturnObject(result.getReturnValue());
                } else {
                    response.setReturnNotifyParamValue(returnNotifyParamValuePre + openRes.getTrxId());
                    response.setRespDesc(result.getMessage());
                    response.setRespCode(result.getCode());
                }
            } else {
                response.setRespCode(openRes.getRespCode());
                response.setRespDesc(openRes.getRespDesc());
            }
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @SuppressWarnings("unchecked")
    @Override
    public QueryBalanceResponse queryBalanceBgRequest(QueryBalanceRequest request) {
        QueryBalanceResponse response = new QueryBalanceResponse();
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getUsrCustId());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version10));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));// 商户客户号
        params.add(new BasicNameValuePair("UsrCustId", request.getUsrCustId()));
        params.add(new BasicNameValuePair("ChkValue", checkValue));

        String resultJsonString = httpRequest(params, partner.getGateWayUrl());
        Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(resultJsonString, HashMap.class);
        if (verifySign(paramMap, VERIFY_KEYS__QUERYBALANCEBG)) {
            response = JsonUtils.createGson().create().fromJson(resultJsonString, QueryBalanceResponse.class);
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;

    }

    @SuppressWarnings("unchecked")
    @Override
    public QueryCardInfoResponseMsg queryCardInfo(QueryCardInfoRequestMsg request) {
        QueryCardInfoResponseMsg response = new QueryCardInfoResponseMsg();
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getUsrCustId());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version10));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));// 商户客户号
        params.add(new BasicNameValuePair("UsrCustId", request.getUsrCustId()));
        params.add(new BasicNameValuePair("ChkValue", checkValue));

        String resultJsonString = httpRequest(params, partner.getGateWayUrl());
        Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(resultJsonString, HashMap.class);
        if (verifySign(paramMap, VERIFY_KEYS__QUERYCARDINFO)) {
            response = JsonUtils.createGson().create().fromJson(resultJsonString, QueryCardInfoResponseMsg.class);
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }
    
    @Override
    public QueryTransDetailResponse queryTransDetail(QueryTransDetailRequest request) {
        QueryTransDetailResponse response = new QueryTransDetailResponse();
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getOrdId()).append(request.getQueryTransType());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version10));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));// 商户客户号
        params.add(new BasicNameValuePair("OrdId", request.getOrdId()));
        params.add(new BasicNameValuePair("QueryTransType", request.getQueryTransType()));
        params.add(new BasicNameValuePair("ChkValue", checkValue));

        String resultJsonString = httpRequest(params, partner.getGateWayUrl());
        logger.info("交易明细状态查询:交易类型: " + request.getQueryTransType() + " 返回JSON串：" + resultJsonString);

        Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(resultJsonString, HashMap.class);
        if (verifySign(paramMap, VERIY_KEYS_FREEUNFREE)) {
            response = JsonUtils.createGson().create().fromJson(resultJsonString, QueryTransDetailResponse.class);
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @SuppressWarnings("unchecked")
    @Override
    public QueryTransStatResponse queryTransStat(QueryTransStatRequest request) {

        QueryTransStatResponse response = new QueryTransStatResponse();
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getOrdId()).append(request.getOrdDate()).append(request.getQueryTransType());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version10));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));// 商户客户号
        params.add(new BasicNameValuePair("OrdId", request.getOrdId()));
        params.add(new BasicNameValuePair("OrdDate", request.getOrdDate()));
        params.add(new BasicNameValuePair("QueryTransType", request.getQueryTransType()));
        params.add(new BasicNameValuePair("ChkValue", checkValue));

        String resultJsonString = httpRequest(params, partner.getGateWayUrl());
        logger.info("交易状态查询:交易类型: " + request.getQueryTransType() + " 返回JSON串：" + resultJsonString);

        Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(resultJsonString, HashMap.class);
        if (verifySign(paramMap, VERIY_KEYS_FREEUNFREE)) {
            response = JsonUtils.createGson().create().fromJson(resultJsonString, QueryTransStatResponse.class);
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @Override
    public ResponseMessage batchRepaymentRequest(RepaymentRequestMsg request) {
        /**
         * 添加一个私有域来标识是否正常还款，还是平台垫付还款 1平台垫付还款 0正常还款
         */
        String merPriv = (request.isPlatfor() ? MSConstants.CHAR_ONE : MSConstants.CHAR_ZERO) + ","
                + request.getRepaymentPlanId();
        RepaymentResponseMsg response = new RepaymentResponseMsg();
        StringLinker sl = new StringLinker();
        sl.append(version20).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getOutCustId()).append(request.getBatchId()).append(request.getMerOrdDate())
                .append(request.getInDetails()).append(request.getBgRetUrl()).append(merPriv)
                .append(request.getProId());

        String checkValue = keyTool.signMessage(MD5.encodeString(sl.toString(), MSConstants.UTF8));// 签名
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version20));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));// 商户客户号
        params.add(new BasicNameValuePair("OutCustId", request.getOutCustId()));
        params.add(new BasicNameValuePair("BatchId", request.getBatchId()));
        params.add(new BasicNameValuePair("MerOrdDate", request.getMerOrdDate()));
        params.add(new BasicNameValuePair("BgRetUrl", request.getBgRetUrl()));
        params.add(new BasicNameValuePair("ProId", request.getProId()));// 借款标的id
        params.add(new BasicNameValuePair("InDetails", request.getInDetails()));
        params.add(new BasicNameValuePair("TransAmt", request.getTransAmt()));
//        params.add(new BasicNameValuePair("Fee", request.getFee()));
        params.add(new BasicNameValuePair("MerPriv", merPriv));
        params.add(new BasicNameValuePair("ChkValue", checkValue));
        logger.info("批量还款请求参数： " + params); 
        httpRequest(params, partner.getGateWayUrl());
        return response;
    }

    @Override
    public NotifyResponseMsg batchRepaymentNotify(NotifyRequestMsg request) {
        /**
         * <pre>
         * 总体思路步骤: 
         * 一,判断返回的信息中失败条数是否为0,以及错误信息是否为空。
         * 二,若失败条数为0： 
         * 		(1)更新还款信息中还款状态为：已还清
         * 		(2)更新对应的收款计划中收款状态为：已收款
         * 		(3)判断借款人的所有还款计划是否已经全部还清，若已经全部还清则更新借款标的状态为：已还清 
         * 		(4)生成还款人的还款资金流水 
         * 		(5)生成收款人的收款资金流水
         * 		(6)更新借款人资金账户表中待还本金,待还利息字段信息,更新收款人资金账户表中累计收益金额,待收本金,待收收益字段信息。
         * 三,失败条数不为0： 
         *   3.1,对于成功执行的部分执行以下操作：
         * 		(1)更新对应的收款计划中收款状态为：已收款 
         * 		(2)生成还款人的还款资金流水,资金流水中的金额就是成功部分的金额总计. 
         * 		(3)生成收款人的收款资金流水
         * 		(4)更新借款人资金账户表中待还本金,待还利息字段信息,更新收款人资金账户表中累计收益金额,待收本金,待收收益字段信息。 
         *   3.2,对于执行失败的部分不做操作。 
         * 四,当还款为平台垫资还款时需生成追偿信息表
         * </pre>
         */
        NotifyResponseMsg response = new NotifyResponseMsg();
        if (verifySign(request.getParameter(), VERIFY_KEYS_BATCH_REPAYMENT)) {
            try {
                RepaymentResponseMsg repaymentRes = JsonUtils.createGson().create()
                        .fromJson(request.getParamString(), RepaymentResponseMsg.class);
                String errorMsg = URLDecoder.decode(repaymentRes.getErrMsg(), MSConstants.UTF8);
                List<RepaymentResponseErrorMsg> retList = JsonUtils.createGson().create()
                        .fromJson(errorMsg, new TypeToken<List<RepaymentResponseErrorMsg>>() {
                        }.getType());
                repaymentRes.setRepaymentErrorMsg(retList);
                if (repaymentRes.getRespCode().equals(RespCodeConstants.CommonCode.TRANS_SUC)) {
                    String[] merPriv = repaymentRes.getMerPriv().split(",");
                    repaymentRes.setMerPriv(merPriv[0]);
                    repaymentRes.setRepaymentPlanId(Long.parseLong(merPriv[1]));
                    ServiceResult<String> result = serviceFactory.getRepaymentService().dealBatchRepaymentResult(
                            repaymentRes);
                    if (result.getIsSuccess()) {
                        response.setReturnNotifyParamValue(returnNotifyParamValuePre + repaymentRes.getBatchId());
                        response.setReturnObject(result.getReturnValue());
                    } else {
                        response.setRespDesc(result.getMessage());
                        response.setRespCode(result.getCode());
                    }
                } else {
                    response.setRespCode(repaymentRes.getRespCode());
                    response.setRespDesc(repaymentRes.getRespDesc());
                }
            } catch (Exception e) {
                e.printStackTrace();
                response.setRespCode(RespCodeConstants.CommonCode.TRANS_FAIL);
                response.setRespDesc(e.getMessage());
            }
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @SuppressWarnings("unchecked")
    @Override
    public RepaymentResponseMsg repaymentRequest(RepaymentRequestMsg request) {
        RepaymentResponseMsg response = new RepaymentResponseMsg();
        String merPriv = request.getMerPriv() + "," + request.getRepaymentPlanId();
        if (StringHelper.isEmpty(request.getMerPriv())) {
            merPriv = request.getRepaymentPlanId();
        }
        StringLinker sl = new StringLinker();
        sl.append(version20).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getOrdId()).append(request.getOrdDate()).append(request.getOutCustId())
                .append(request.getSubOrdId()).append(request.getSubOrdDate()).append(request.getTransAmt())
                .append(request.getFee()).append(request.getInCustId()).append(request.getInAcctId())
                .append(request.getBgRetUrl()).append(request.getMerPriv())
                .append("{\"ProId\":\"" + request.getBorrowinfoId() + "\"}");
        String checkValue = keyTool.signMessage(sl.toString());// 签名
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version20));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));// 商户客户号
        params.add(new BasicNameValuePair("OrdId", request.getOrdId()));
        params.add(new BasicNameValuePair("OrdDate", request.getOrdDate()));
        params.add(new BasicNameValuePair("OutCustId", request.getOutCustId()));
        params.add(new BasicNameValuePair("SubOrdId", request.getSubOrdId()));
        params.add(new BasicNameValuePair("SubOrdDate", request.getSubOrdDate()));
        params.add(new BasicNameValuePair("TransAmt", request.getTransAmt()));
        params.add(new BasicNameValuePair("Fee", request.getFee()));
        params.add(new BasicNameValuePair("InCustId", request.getInCustId()));
        params.add(new BasicNameValuePair("InAcctId", request.getInAcctId()));
        params.add(new BasicNameValuePair("BgRetUrl", request.getBgRetUrl()));
        params.add(new BasicNameValuePair("ChkValue", checkValue));
        params.add(new BasicNameValuePair("MerPriv", merPriv));
        params.add(new BasicNameValuePair("ReqExt", "{\"ProId\":\"" + request.getBorrowinfoId() + "\"}"));
        logger.info("还款接口：订单编号： " + request.getOrdId() + ",请求参数:" + params.toString());
        String resultJsonString = httpRequest(params, partner.getGateWayUrl());
        logger.info("还款接口：订单编号： " + request.getOrdId() + ",请求返回JSON串：" + resultJsonString);
        Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(resultJsonString, HashMap.class);
        if (verifySign(paramMap, VERIFY_KEYS_REPAYMENT)) {
            response = JsonUtils.createGson().create().fromJson(resultJsonString, RepaymentResponseMsg.class);
            response.setMerPriv(request.getMerPriv());
            response.setRepaymentPlanId(Long.parseLong(request.getRepaymentPlanId()));
            ServiceResult<String> result = serviceFactory.getRepaymentService().dealRepaymentResult(response);
            if (result.getIsSuccess()) {
                response.setReturnNotifyParamValue(returnNotifyParamValuePre + response.getOrdId());
                response.setRespCode(RespCodeConstants.CommonCode.TRANS_SUC);
                response.setRespDesc(RespCodeConstants.CommonCode.TRANS_SUC_MSG);
            } else {
                response.setRespCode(result.getCode());
                response.setRespDesc(result.getMessage());
            }
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @Override
    public NotifyResponseMsg repaymentNotify(NotifyRequestMsg request) {
        NotifyResponseMsg response = new NotifyResponseMsg();
        if (verifySign(request.getParameter(), VERIFY_KEYS_REPAYMENT)) {
            RepaymentResponseMsg repaymentRes = JsonUtils.createGson().create()
                    .fromJson(request.getParamString(), RepaymentResponseMsg.class);
            String[] merPriv = repaymentRes.getMerPriv().split(",");
            if (merPriv.length == 2) {
                repaymentRes.setMerPriv(merPriv[0]);
                repaymentRes.setRepaymentPlanId(Long.parseLong(merPriv[1]));
            }
            ServiceResult<String> result = serviceFactory.getRepaymentService().dealRepaymentResult(repaymentRes);
            if (result.getIsSuccess()) {
                response.setReturnNotifyParamValue(returnNotifyParamValuePre + repaymentRes.getOrdId());
                response.setReturnObject(result.getReturnValue());
            } else {
                response.setRespDesc(result.getMessage());
                response.setRespCode(result.getCode());
            }
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @SuppressWarnings("unchecked")
    @Override
    public QueryAcctsResponseMsg queryAcctsRequest(QueryAcctsRequestMsg request) {
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version10));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));// 商户客户号
        params.add(new BasicNameValuePair("ChkValue", checkValue));

        String resultJsonString = httpRequest(params, partner.getGateWayUrl());
        // {"CmdId":"QueryAccts","RespCode":"000","RespDesc":"成功","ChkValue":"9A218101376A6EC9576D8E5E583F6021079A0F286A002CFA379010E5E6A0342D9C5FE0FC606817A2F98B903C21CEE6EC782723EAB8AECF004E883768420D04D8C3B5A058FE1D9F0848B78A8F720C983220730290BF4AB887E28BE314D826CC52255283246A95695873BA158B7BD919BA782CCAA8D0ABBEB92FAA57278EBAC8F1","Version":null,"MerCustId":"6000060000002526","AcctDetails":[{"AcctType":"BASEDT","SubAcctId":"BASEDT","AvlBal":"0.00","AcctBal":"0.00","FrzBal":"0.00"},{"AcctType":"MERDT","SubAcctId":"MDT000001","AvlBal":"988867.15","AcctBal":"988867.15","FrzBal":"0.00"},{"AcctType":"MERDT","SubAcctId":"MDT000003","AvlBal":"1010206.52","AcctBal":"1010206.52","FrzBal":"0.00"},{"AcctType":"MERDT","SubAcctId":"MDT000004","AvlBal":"1000110.00","AcctBal":"1000110.00","FrzBal":"0.00"},{"AcctType":"SPEDT","SubAcctId":"SDT000001","AvlBal":"999899.98","AcctBal":"999899.98","FrzBal":"0.00"}],"PlaintStr":"QueryAccts0006000060000002526"}
        Map<String, String> paramMap = (JsonUtils.createGson().create().fromJson(resultJsonString, HashMap.class));
        if (verifySign(paramMap, VERIFY_KEYS_QUERY_ACCT)) {
            return JsonUtils.createGson().create().fromJson(resultJsonString, QueryAcctsResponseMsg.class);
        } else {
            return null;
        }
    }

    @Override
    public InvestInfoResponseMsg packageInitiativeTenderRequest(InvestInfoRequestMsg request) {
        InvestInfoResponseMsg response = new InvestInfoResponseMsg();
        StringLinker sl = new StringLinker();
        sl.append(version20).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getInvestInfoId().toString()).append(request.getOrdDate())
                .append(MoneyUtil.convertFenToYuan(Long.parseLong(request.getTransAmt())))
                .append(request.getUsrCustId()).append(max_Tender_Rate).append(request.getBorrowerDetails())
                .append(request.getIsFreeze()).append(request.getFreezeOrdId()).append(request.getRetUrl())
                .append(request.getBgRetUrl());
        if (request.getPageType() != null && request.getPageType().equals("2")) {
            sl.append("2");
        }

        String checkValue = keyTool.signMessage(sl.toString());// 签名
        ParamHash pl = new ParamHash();
        pl.append("Version", version20).append("CmdId", request.getPartnerTransType().getType())
                .append("MerCustId", partner.getMerchantId()).append("OrdId", request.getInvestInfoId().toString())
                .append("OrdDate", request.getOrdDate())
                .append("TransAmt", MoneyUtil.convertFenToYuan(Long.parseLong(request.getTransAmt())))
                .append("UsrCustId", request.getUsrCustId()).append("MaxTenderRate", max_Tender_Rate)
                .append("BorrowerDetails", request.getBorrowerDetails()).append("IsFreeze", request.getIsFreeze())
                .append("FreezeOrdId", request.getFreezeOrdId()).append("RetUrl", request.getRetUrl())
                .append("BgRetUrl", request.getBgRetUrl()).append("ChkValue", checkValue);
        if (request.getPageType() != null && request.getPageType().equals("2")) {
            pl.append("PageType", "2");
        }
        String htmlString = null;
        htmlString = autoSubmitHtmlFormJSON(MSConstants.UTF8, request.getPartnerTransType().getText(),
                partner.getGateWayUrl(), pl.getParams(), "POST");
        logger.info(request.getPartnerTransType().getType() + "生成的表单内容为：\n" + htmlString);

        response.setOrderFormContent(htmlString);
        response.setRespCode(RespCodeConstants.CommonCode.TRANS_SUC);
        return response;
    }

    @Override
    public NotifyResponseMsg initiativeTenderNotify(NotifyRequestMsg request) {
        NotifyResponseMsg response = new NotifyResponseMsg();
        if (verifySign(request.getParameter(), VERIFY_KEYS_INITIATIVETENDER)) {
            InvestInfoResponseMsg investInfoResponseMsg = JsonUtils.createGson().create()
                    .fromJson(request.getParamString(), InvestInfoResponseMsg.class);

            ServiceResult<String> result = serviceFactory.getInvestInfoService()
                    .dealInvestResult(investInfoResponseMsg);
            if (result.getIsSuccess()) {
                response.setReturnNotifyParamValue(returnNotifyParamValuePre + investInfoResponseMsg.getOrdId());
                response.setReturnObject(result.getReturnValue());
            } else {
                response.setRespDesc(result.getMessage());
                response.setRespCode(result.getCode());
            }
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @Override
    public ResponseMessage packagePayRequest(PayRequestMsg request) {
        // Version +CmdId + MerCustId + UsrCustId + OrdId+ OrdDate + GateBusiId+
        // OpenBankId+ DcFlag +TransAmt+ RetUrl+ BgRetUrl+ OpenAcctId+ CertId+
        // MerPriv
        Double doubleMoney = Double.parseDouble(request.getTransAmt()) * 100;
        request.setTransAmt(MoneyUtil.convertFenToYuan(doubleMoney.longValue()));

        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getUsrCustId()).append(request.getOrdId()).append(request.getOrdDate())
                .append(request.getTransAmt());
        if (StringHelper.isEmpty(request.getRetUrl())) {
            sl.append(request.getRetUrl());
        } else {
            sl.append(request.getRetUrl());
        }
        if (StringHelper.isEmpty(request.getBgRetUrl())) {
            sl.append(request.getBgRetUrl());
        } else {
            sl.append(request.getBgRetUrl());
        }
        if (request.getPageType() != null && request.getPageType().equals("2")) {
            sl.append("2");
        }
        String checkValue = keyTool.signMessage(sl.toString());// 签名

        ParamHash pl = new ParamHash();
        pl.append("Version", version10).append("CmdId", request.getPartnerTransType().getType())
                .append("MerCustId", partner.getMerchantId()).append("UsrCustId", request.getUsrCustId())
                .append("OrdId", request.getOrdId()).append("OrdDate", request.getOrdDate())
                .append("ChkValue", checkValue);

        if (StringHelper.isEmpty(request.getRetUrl())) {
            pl.append("RetUrl", request.getRetUrl());
        } else {
            pl.append("RetUrl", request.getRetUrl());
        }
        if (StringHelper.isEmpty(request.getBgRetUrl())) {
            pl.append("BgRetUrl", request.getBgRetUrl());
        } else {
            pl.append("BgRetUrl", request.getBgRetUrl());
        }
        pl.append("TransAmt", request.getTransAmt());
        if (request.getPageType() != null && request.getPageType().equals("2")) {
            pl.append("PageType", "2");
        }
        String htmlString = null;

        htmlString = WebClientUtil.autoSubmitHtmlForm(MSConstants.UTF8, request.getPartnerTransType().getText(),
                partner.getGateWayUrl(), pl.getParams(), "POST");
        logger.info(request.getPartnerTransType().getType() + "生成的表单内容为：\n" + htmlString);

        ResponseMessage response = new ResponseMessage();
        response.setOrderFormContent(htmlString);
        response.setRespCode(RespCodeConstants.CommonCode.TRANS_SUC);
        return response;
    }

    @Override
    public NotifyResponseMsg payNotify(NotifyRequestMsg request) {
        NotifyResponseMsg response = new NotifyResponseMsg();
        if (verifySign(request.getParameter(), VERIFY_KEYS_NET_SAVE)) {
            PayResponseMsg res = null;
            res = new PayResponseMsg();
            res.setRespCode(request.getParameter().get("RespCode"));
            res.setRespDesc(request.getParameter().get("RespDesc"));
            res.setMerPriv(request.getParameter().get("MerPriv"));
            res.setUsrCustId(request.getParameter().get("UsrCustId"));
            res.setTrxId(request.getParameter().get("TrxId"));
            res.setOrdId(request.getParameter().get("OrdId"));
            res.setOrdDate(request.getParameter().get("OrdDate"));
            res.setTransAmt(request.getParameter().get("TransAmt"));
            res.setFeeAcctId(request.getParameter().get("FeeAcctId"));
            res.setFeeAmt(request.getParameter().get("FeeAmt"));
            res.setFeeCustId(request.getParameter().get("FeeCustId"));

            if (res.getRespCode().equals(RespCodeConstants.CommonCode.TRANS_SUC)) {
                response.setRespCode(res.getRespCode());
                response.setRespDesc(res.getRespDesc());
                ServiceResult<Payment> result = serviceFactory.getPaymentService().dealPayResult(res);
                if (result.getIsSuccess()) {
                    response.setReturnNotifyParamValue(returnNotifyParamValuePre + res.getTrxId());
                    response.setReturnObject(result.getReturnValue());
                } else {
                    response.setReturnNotifyParamValue(returnNotifyParamValuePre + res.getTrxId());
                    response.setRespDesc(result.getMessage());
                    response.setRespCode(result.getCode());
                }

            } else {
                // 处理失败的订单
                serviceFactory.getPaymentService().dealPayResult(res);
                response.setRespCode(res.getRespCode());
                response.setRespDesc(res.getRespDesc());

            }
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @Override
    public ResponseMessage packageDrawRequest(CashRequestMsg request) {
        // Version +CmdId + MerCustId+ OrdId + UsrCustId + TransAmt+ ServFee+
        // ServFeeAcctId +OpenAcctId + RetUrl +
        // BgRetUrl+ Remark+ MerPriv + ReqExt
        Double transAmt = (new BigDecimal(request.getTransAmt())).multiply(new BigDecimal(100)).doubleValue();
        request.setTransAmt(String.valueOf(MoneyUtil.convertFenToYuanDouble(transAmt)));
        StringLinker sl = new StringLinker();
        sl.append(version20).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getOrdId()).append(request.getUsrCustId()).append(request.getTransAmt())
                .append(request.getRetUrl()).append(request.getBgRetUrl());
        sl.append("[{\"CashChl\":\"GENERAL\"}]"); //普通取现(T+1)
        if (request.getPageType() != null && request.getPageType().equals("2")) {
            sl.append("2");
        }
        String checkValue = keyTool.signMessage(sl.toString());// 签名

        ParamHash pl = new ParamHash();
        pl.append("Version", version20).append("CmdId", request.getPartnerTransType().getType())
                .append("MerCustId", partner.getMerchantId()).append("UsrCustId", request.getUsrCustId())
                .append("OrdId", request.getOrdId()).append("ChkValue", checkValue)
                .append("RetUrl", request.getRetUrl()).append("BgRetUrl", request.getBgRetUrl())
                .append("TransAmt", request.getTransAmt());
        if (request.getPageType() != null && request.getPageType().equals("2")) {
            pl.append("PageType", "2");
        }
        //普通取现
        pl.append("ReqExt","[{&quot;CashChl&quot;:&quot;GENERAL&quot;}]");
        
        String htmlString = null;

        htmlString = WebClientUtil.autoSubmitHtmlForm(MSConstants.UTF8, request.getPartnerTransType().getText(),
                partner.getGateWayUrl(), pl.getParams(), "POST");
        logger.info(request.getPartnerTransType().getType() + "生成的表单内容为：\n" + htmlString);

        ResponseMessage response = new ResponseMessage();
        response.setOrderFormContent(htmlString);
        response.setRespCode(RespCodeConstants.CommonCode.TRANS_SUC);
        return response;
    }

    @Override
    public NotifyResponseMsg drawNotify(NotifyRequestMsg request) {
        NotifyResponseMsg response = new NotifyResponseMsg();
        // 判断用什么验签
        String[] checkKey = VERIFY_KEYS_CASH_RETURN;// 取现返回
        String cmdId = request.getParameter().get("CmdId");
        if (cmdId == null || cmdId.equals("")) {
            checkKey = VERIFY_KEYS_CASH_RECONCIL;// 取现对账通知
        }

        if (verifySign(request.getParameter(), checkKey)) {
            CashResponseMsg res = null;
            res = new CashResponseMsg();
            res.setRespCode(request.getParameter().get("RespCode"));
            res.setRespDesc(request.getParameter().get("RespDesc"));
            res.setUsrCustId(request.getParameter().get("UsrCustId"));
            res.setOrdId(request.getParameter().get("OrdId"));
            res.setTransAmt(request.getParameter().get("TransAmt"));
            res.setFeeAcctId(request.getParameter().get("FeeAcctId"));
            res.setFeeAmt(request.getParameter().get("FeeAmt"));
            res.setFeeCustId(request.getParameter().get("FeeCustId"));
            res.setMerPriv(request.getParameter().get("MerPriv"));

            if (res.getRespCode().equals(RespCodeConstants.CommonCode.TRANS_SUC)) {
                response.setRespCode(res.getRespCode());
                response.setRespDesc(res.getRespDesc());
                ServiceResult<Payment> result = serviceFactory.getPaymentService().dealDrawResult(res);
                if (result.getIsSuccess()) {
                    response.setReturnNotifyParamValue(returnNotifyParamValuePre + res.getOrdId());
                    response.setReturnObject(result.getReturnValue());

                } else {
                    response.setReturnNotifyParamValue(returnNotifyParamValuePre + res.getOrdId());
                    response.setRespDesc(result.getMessage());
                    response.setRespCode(result.getCode());
                }
            } else {
                // 处理失败的订单
                serviceFactory.getPaymentService().dealDrawResult(res);
                response.setRespCode(res.getRespCode());
                response.setRespDesc(res.getRespDesc());
            }
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    /**
     * <pre>
     * 标的信息录入
     * </pre>
     * 
     * @param request
     * @return
     */
    @Override
    @SuppressWarnings("unchecked")
    public AddBidInfoResponse addBidInfo(AddBidInfoRequest request) {
        try {
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("Version", version10));
            params.add(new BasicNameValuePair("CmdId", "AddBidInfo"));
            params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));
            params.add(new BasicNameValuePair("ProId", request.getProId()));
            params.add(new BasicNameValuePair("BorrCustId", request.getBorrCustId()));
            params.add(new BasicNameValuePair("BorrTotAmt", request.getBorrTotAmt()));
            params.add(new BasicNameValuePair("YearRate", request.getYearRate()));
            params.add(new BasicNameValuePair("RetType", request.getRetType()));
            params.add(new BasicNameValuePair("BidStartDate", request.getBidStartDate()));
            params.add(new BasicNameValuePair("BidEndDate", request.getBidEndDate()));
            params.add(new BasicNameValuePair("RetAmt", request.getRetAmt()));
            params.add(new BasicNameValuePair("RetDate", request.getRetDate()));
            /**
             * 暂时注释掉担保公司信息,以下两行代码先不删除
             */
            // params.add(new BasicNameValuePair("GuarCompId",
            // request.getGuarCompId()));
            // params.add(new BasicNameValuePair("GuarAmt",
            // request.getGuarAmt()));
            params.add(new BasicNameValuePair("ProArea", request.getProArea()));
            params.add(new BasicNameValuePair("BgRetUrl", request.getBgRetUrl()));
            addChkValue(params, SignKey.AddBidInfo.getRequestKey());
            logger.info("标的录入编号:" + request.getProId() + ",请求消息:" + params.toString());
            String rtstring = httpRequest(params, partner.getGateWayUrl());
            if (!StringHelper.isEmpty(rtstring)) {
                rtstring = URLDecoder.decode(rtstring, "UTF-8");
                logger.info("标的录入编号:" + request.getProId() + ",响应消息:" + rtstring);
                Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(rtstring, HashMap.class);
                if (verifySign(paramMap, SignKey.AddBidInfo.getResponseKey())) {
                    return JsonUtils.createGson().create().fromJson(rtstring, AddBidInfoResponse.class);
                } else {
                    logger.error("借款编号:" + request.getProId() + ",进行标的信息录入到汇付时,请求响应加密摘要验证不匹配");
                    return null;
                }
            } else {
                logger.error("借款编号:" + request.getProId() + ",进行标的信息录入到汇付时,响应为空或者连接出现异常");
                return null;
            }
        } catch (Exception e) {
            throw new SystemException(e);
        }
    }

    @SuppressWarnings("unchecked")
    public LoansResponse loans(LoansRequest request) {
        try {
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("Version", version20));
            params.add(new BasicNameValuePair("CmdId", "Loans"));
            params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));
            params.add(new BasicNameValuePair("OrdId", request.getOrdId()));
            params.add(new BasicNameValuePair("OrdDate", request.getOrdDate()));
            params.add(new BasicNameValuePair("OutCustId", request.getOutCustId()));
            params.add(new BasicNameValuePair("TransAmt", request.getTransAmt()));
            params.add(new BasicNameValuePair("Fee", request.getFee()));
            params.add(new BasicNameValuePair("SubOrdId", request.getSubOrdId()));
            params.add(new BasicNameValuePair("SubOrdDate", request.getSubOrdDate()));
            params.add(new BasicNameValuePair("InCustId", request.getInCustId()));
            params.add(new BasicNameValuePair("DivDetails", request.getDivDetails()));
            params.add(new BasicNameValuePair("FeeObjFlag", request.getFeeObjFlag()));
            params.add(new BasicNameValuePair("IsDefault", request.getIsDefault()));
            params.add(new BasicNameValuePair("FreezeTrxId", request.getFreezeTrxId()));
            params.add(new BasicNameValuePair("IsUnFreeze", request.getIsUnFreeze()));
            params.add(new BasicNameValuePair("UnFreezeOrdId", request.getUnFreezeOrdId()));
            params.add(new BasicNameValuePair("ReqExt", request.getReqExt()));
            params.add(new BasicNameValuePair("BgRetUrl", request.getBgRetUrl()));
            addChkValue(params, SignKey.LAON.getRequestKey());
            logger.info("投资放款编号:" + request.getOrdId() + ",请求消息:" + params.toString());
            String rtstring = httpRequest(params, partner.getGateWayUrl());
            logger.info("投资放款编号:" + request.getOrdId() + ",放款实时响应消息:" + rtstring);
            if (!StringHelper.isEmpty(rtstring)) {
                rtstring = URLDecoder.decode(rtstring, "UTF-8");
                String s1 = rtstring.replaceAll(".*\\\"RespExt\\\"\\s*:\\s*\\\"\\{([^}]*)\\}\\\",.*", "$1");
                String s2 = s1.replaceAll("\"", "\\\\\\\\\\\\\\\"");
                rtstring = rtstring.replaceAll(s1, s2);
                Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(rtstring, HashMap.class);
                if (verifySign(paramMap, SignKey.LAON.getResponseKey())) {
                    return JsonUtils.createGson().create().fromJson(rtstring, LoansResponse.class);
                } else {
                    logger.error("投资编号:" + request.getOrdId() + ",进行标的放款时,请求响应加密摘要验证不匹配");
                    return null;
                }
            } else {
                logger.error("投资编号:" + request.getOrdId() + ",进行标的放款时,响应为空或者连接出现异常");
                return null;
            }
        } catch (Exception e) {
            throw new SystemException(e);
        }
    }

    @SuppressWarnings("unchecked")
    public UsrUnFreezeResponse usrUnFreeze(UsrUnFreezeRequest request) {
        try {
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("Version", version10));
            params.add(new BasicNameValuePair("CmdId", "UsrUnFreeze"));
            params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));
            params.add(new BasicNameValuePair("OrdId", request.getOrdId()));
            params.add(new BasicNameValuePair("OrdDate", request.getOrdDate()));
            params.add(new BasicNameValuePair("TrxId", request.getTrxId()));
            params.add(new BasicNameValuePair("BgRetUrl", request.getBgRetUrl()));
            addChkValue(params, SignKey.UsrUnFreeze.getRequestKey());
            logger.info("投标编号:" + request.getOrdId() + "解冻,请求消息:" + params.toString());
            String rtstring = httpRequest(params, partner.getGateWayUrl());
            if (!StringHelper.isEmpty(rtstring)) {
                rtstring = URLDecoder.decode(rtstring, "UTF-8");
                logger.info("投标编号:" + request.getOrdId() + "解冻,响应消息:" + rtstring);
                Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(rtstring, HashMap.class);
                if (verifySign(paramMap, SignKey.UsrUnFreeze.getResponseKey())) {
                    return JsonUtils.createGson().create().fromJson(rtstring, UsrUnFreezeResponse.class);
                } else {
                    logger.error("投资编号:" + request.getOrdId() + ",进行资金解冻时,请求响应加密摘要验证不匹配");
                    return null;
                }
            } else {
                logger.error("投资编号:" + request.getOrdId() + ",进行资金解冻时,响应为空或者连接出现异常");
                return null;
            }
        } catch (Exception e) {
            serviceFactory.getSystemLogService().addLog("",request.getOrdId(), LogType.SYSTEMERROR, e.getMessage());
            throw new SystemException(e);
        }
    }

    public TenderCancleResponse tenderCancle(TenderCancleRequest request) {
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version20));
        params.add(new BasicNameValuePair("CmdId", "TenderCancle"));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));
        params.add(new BasicNameValuePair("OrdId", request.getOrdId()));
        params.add(new BasicNameValuePair("OrdDate", request.getOrdDate()));
        params.add(new BasicNameValuePair("TransAmt", request.getTransAmt()));
        params.add(new BasicNameValuePair("UsrCustId", request.getUsrCustId()));
        params.add(new BasicNameValuePair("IsUnFreeze", request.getIsUnFreeze()));
        params.add(new BasicNameValuePair("UnFreezeOrdId", request.getUnFreezeOrdId()));
        params.add(new BasicNameValuePair("MerPriv", request.getMerPriv()));
        params.add(new BasicNameValuePair("BgRetUrl", request.getBgRetUrl()));
        addChkValue(params, SignKey.TenderCancle.getRequestKey());
        Map<String, String> map = new HashMap<String, String>();
        for (NameValuePair nameValuePair : params) {
            map.put(nameValuePair.getName(), nameValuePair.getValue());
        }
        String htmlString = WebClientUtil.autoSubmitHtmlForm(MSConstants.UTF8, request.getPartnerTransType().getText(),
                partner.getGateWayUrl(), map, "POST");
        logger.info(request.getPartnerTransType().getType() + "生成的表单内容为：\n" + htmlString);
        TenderCancleResponse response = new TenderCancleResponse();
        response.setOrderFormContent(htmlString);
        response.setRespCode(RespCodeConstants.CommonCode.TRANS_SUC);
        return response;
    }

    /**
     * <pre>
     * 放款通知
     * </pre>
     * 
     * @param request
     * @return
     */
    @Override
    public NotifyResponseMsg loansNotify(NotifyRequestMsg request) {
        NotifyResponseMsg response = new NotifyResponseMsg();
        try {
            String rtstring = URLDecoder.decode(request.getParamString(), "UTF-8");
            if (verifySign(request.getParameter(), SignKey.LAON.getResponseKey())) {
                LoansResponse loanResponse = JsonUtils.createGson().create().fromJson(rtstring, LoansResponse.class);
                if (RespCodeConstants.CommonCode.TRANS_SUC.equals(loanResponse.getRespCode())
                        || RespCodeConstants.BorrowInfoCode.TRANSMESSAGE_ERRCODE_LOANED.equals(loanResponse.getRespCode())) {
                    response.setRespCode(loanResponse.getRespCode());
                    response.setRespDesc(loanResponse.getRespDesc());
                    ServiceResult<String> result = serviceFactory.getBorrowService().loansResponse(loanResponse);
                    if (result.getIsSuccess()) {
                        response.setReturnNotifyParamValue(returnNotifyParamValuePre + loanResponse.getOrdId());
                        response.setReturnObject(result.getReturnValue());
                    } else {
                        response.setRespDesc(result.getMessage());
                        response.setRespCode(result.getCode());
                    }
                } else {
                    logger.error("投资Id:" + loanResponse.getOrdId() + ",汇付放款失败"
                            + ObjectHelper.toPropertiesString(loanResponse));
                    response.setRespCode(loanResponse.getRespCode());
                    response.setRespDesc(loanResponse.getRespDesc());
                }
            } else {
                response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
                response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
            }
            return response;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    /**
     * <pre>
     * 资金解冻通知
     * </pre>
     * 
     * @param request
     * @return
     */
    public NotifyResponseMsg usrUnFreezeNotify(NotifyRequestMsg request) {
        try {
            NotifyResponseMsg response = new NotifyResponseMsg();
            String rtstring = URLDecoder.decode(request.getParamString(), "UTF-8");
            if (verifySign(request.getParameter(), SignKey.UsrUnFreeze.getResponseKey())) {
                UsrUnFreezeResponse usrResponse = JsonUtils.createGson().create()
                        .fromJson(rtstring, UsrUnFreezeResponse.class);
                if (RespCodeConstants.CommonCode.TRANS_SUC.equals(usrResponse.getRespCode())) {
                    response.setRespCode(usrResponse.getRespCode());
                    response.setRespDesc(usrResponse.getRespDesc());
                    ServiceResult<String> result = serviceFactory.getBorrowService().lossResponse(usrResponse);
                    if (result.getIsSuccess()) {
                        response.setReturnNotifyParamValue(returnNotifyParamValuePre + usrResponse.getOrdId());
                        response.setReturnObject(result.getReturnValue());
                    } else {
                        response.setRespDesc(result.getMessage());
                        response.setRespCode(result.getCode());
                    }
                } else {
                    logger.error("投资Id:" + usrResponse.getOrdId() + ",汇付撤标解冻失败"
                            + ObjectHelper.toPropertiesString(usrResponse));
                    response.setRespCode(usrResponse.getRespCode());
                    response.setRespDesc(usrResponse.getRespDesc());
                }
            } else {
                response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
                response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
            }
            return response;
        } catch (Exception e) {
            throw new SystemException(e);
        }
    }

    public void addChkValue(List<NameValuePair> params, String[] keys) {
        Map<String, String> map = new HashMap<String, String>();
        for (NameValuePair nameValuePair : params) {
            if (!StringHelper.isEmpty(nameValuePair.getValue())) {
                map.put(nameValuePair.getName(), nameValuePair.getValue());
            }
        }
        StringLinker sl = new StringLinker();
        for (String key : keys) {
            String value = map.get(key);
            if (!StringHelper.isEmpty(value)) {
                sl.append(value);
            }
        }
        String checkValue = keyTool.signMessage(sl.toString());// 签名
        params.add(new BasicNameValuePair("ChkValue", checkValue));
    }

    @Override
    @SuppressWarnings("unchecked")
    public ResponseMessage queryCorpOpenRequest(CorpRegisterQueryRequest request) {
        CorpRegisterQueryResponse response = new CorpRegisterQueryResponse();
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version10));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));
        params.add(new BasicNameValuePair("BusiCode", request.getBusiCode()));

        // Version+CmdId+MerCustId+BusiCode +ReqExt
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getBusiCode());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        params.add(new BasicNameValuePair("ChkValue", checkValue));

        String returnJson = httpRequest(params, partner.getGateWayUrl());
        CorpRegisterQueryResponse returnMsg = new CorpRegisterQueryResponse();
        try {
            returnMsg = JsonUtils.createGson().create()
                    .fromJson(URLDecoder.decode(returnJson, "utf-8"), CorpRegisterQueryResponse.class);
        } catch (JsonSyntaxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Map<String, String> paramMap = (JsonUtils.createGson().create().fromJson(returnJson, HashMap.class));
        if (verifySign(paramMap, VERIFY_KEYS_QUERY_CORPREGISTER)) {
            if (returnMsg.getAuditStat() == null) {
                response.setRespCode(returnMsg.getRespCode());
                response.setRespDesc(returnMsg.getRespDesc());
                return response;
            } else {
                response.setRespDesc(AuditStat.valueOf(returnMsg.getAuditStat()).getText());
            }
            serviceFactory.getUserInfoService().dealCorpRegisterQueryResult(returnMsg);
            return returnMsg;
        } else {
            response.setRespCode(returnMsg.getRespCode());
            response.setRespDesc(returnMsg.getRespDesc());
            return response;
        }
    }

    @Override
    public ResponseMessage packageBindCardRequest(BindCardRequest request) {
        // Version + CmdId + MerCustId + UsrCustId + BgRetUrl+MerPriv
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getUsrCustId()).append(request.getBgRetUrl());
        if (request.getPageType() != null && request.getPageType().equals("2")) {
            sl.append("2");
        }
        String checkValue = keyTool.signMessage(sl.toString());// 签名

        ParamHash pl = new ParamHash();
        pl.append("Version", version10).append("CmdId", request.getPartnerTransType().getType())
                .append("MerCustId", partner.getMerchantId()).append("UsrCustId", request.getUsrCustId())
                .append("ChkValue", checkValue).append("BgRetUrl", request.getBgRetUrl());
        if (request.getPageType() != null && request.getPageType().equals("2")) {
            pl.append("PageType", "2");
        }
        String htmlString = null;

        htmlString = WebClientUtil.autoSubmitHtmlForm(MSConstants.UTF8, request.getPartnerTransType().getText(),
                partner.getGateWayUrl(), pl.getParams(), "POST");
        logger.info(request.getPartnerTransType().getType() + "生成的表单内容为：\n" + htmlString);

        ResponseMessage response = new ResponseMessage();
        response.setOrderFormContent(htmlString);
        response.setRespCode(RespCodeConstants.CommonCode.TRANS_SUC);
        return response;
    }

    @Override
    public NotifyResponseMsg bindCardNotify(NotifyRequestMsg request) {
        NotifyResponseMsg response = new NotifyResponseMsg();
        if (verifySign(request.getParameter(), VERIFY_KEYS_BINDCARD)) {
            BindCardResponse res = null;
            res = new BindCardResponse();
            res.setRespCode(request.getParameter().get("RespCode"));
            res.setRespDesc(request.getParameter().get("RespDesc"));
            res.setUsrCustId(request.getParameter().get("UsrCustId"));
            res.setMerPriv(request.getParameter().get("MerPriv"));
            res.setTrxId(request.getParameter().get("TrxId"));
            response.setRespCode(res.getRespCode());
            response.setRespDesc(res.getRespDesc());
            ServiceResult<UserInfo> result = serviceFactory.getUserInfoService().dealBindCardResult(res);
            if (result.getIsSuccess()) {// 处理成功
                if (res.getRespCode().equals(RespCodeConstants.CommonCode.TRANS_SUC)) {
                    response.setReturnNotifyParamValue(returnNotifyParamValuePre + res.getTrxId());
                } else {
                    response.setReturnNotifyParamValue(returnNotifyParamValuePre + res.getTrxId());
                    response.setRespCode(RespCodeConstants.CommonCode.TRANS_FAIL);
                    response.setRespDesc(res.getRespDesc());
                }
            }
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @SuppressWarnings("unchecked")
    @Override
    public TransferResponse packageTransferRequest(TransferRequest request) {
        TransferResponse response = new TransferResponse();

        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(request.getOrdId())
                .append(request.getOutCustId()).append(request.getOutAcctId()).append(request.getTransAmt())
                .append(request.getInCustId()).append(request.getInAcctId())
                // .append(request.getRetUrl())
                .append(request.getBgRetUrl());

        if (!StringHelper.isEmpty(request.getMerPriv())) {
            sl.append(request.getMerPriv());
        }

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version10));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("OrdId", request.getOrdId()));
        params.add(new BasicNameValuePair("ChkValue", checkValue));
        params.add(new BasicNameValuePair("OutCustId", request.getOutCustId()));
        params.add(new BasicNameValuePair("OutAcctId", request.getOutAcctId()));
        params.add(new BasicNameValuePair("TransAmt", request.getTransAmt()));
        params.add(new BasicNameValuePair("InCustId", request.getInCustId()));
        params.add(new BasicNameValuePair("InAcctId", request.getInAcctId()));
        params.add(new BasicNameValuePair("RetUrl", ""));
        params.add(new BasicNameValuePair("BgRetUrl", request.getBgRetUrl()));

        if (!StringHelper.isEmpty(request.getMerPriv())) {
            params.add(new BasicNameValuePair("MerPriv", request.getMerPriv()));
        }

        String resultJsonString = httpRequest(params, partner.getGateWayUrl());
        Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(resultJsonString, HashMap.class);
        if (verifySign(paramMap, VERIFY_KEYS_TRANSFER)) {
            response = JsonUtils.createGson().create().fromJson(resultJsonString, TransferResponse.class);
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @Override
    public NotifyResponseMsg transferNotify(NotifyRequestMsg request) {
        NotifyResponseMsg response = new NotifyResponseMsg();
        if (verifySign(request.getParameter(), VERIFY_KEYS_TRANSFER)) {
            TransferResponse res = null;
            res = new TransferResponse();
            res.setRespCode(request.getParameter().get("RespCode"));
            res.setRespDesc(request.getParameter().get("RespDesc"));
            res.setMerPriv(request.getParameter().get("MerPriv"));
            res.setOrdId(request.getParameter().get("OrdId"));
            res.setOutCustId(request.getParameter().get("OutCustId"));
            res.setOutAcctId(request.getParameter().get("OutAcctId"));
            res.setTransAmt(request.getParameter().get("TransAmt"));
            res.setInCustId(request.getParameter().get("InCustId"));
            res.setInAcctId(request.getParameter().get("InAcctId"));

            response.setRespCode(res.getRespCode());
            response.setRespDesc(res.getRespDesc());

            ServiceResult<Transfer> result = serviceFactory.getTransferService().dealTransferResult(res);
            if (result.getIsSuccess()) {// 处理成功
                if (res.getRespCode().equals(RespCodeConstants.CommonCode.TRANS_SUC)) {
                    response.setReturnNotifyParamValue(returnNotifyParamValuePre + res.getOrdId());
                    response.setReturnObject(res);
                } else {
                    response.setRespCode(RespCodeConstants.CommonCode.TRANS_FAIL);
                    response.setRespDesc(res.getRespDesc());
                    response.setReturnObject(res);
                }
            }

        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @Override
    public ResponseMessage packageModifyRequest(ModifyRequest request) {
        // Version +CmdId + MerCustId + UsrCustId
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getUsrCustId());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        ParamHash pl = new ParamHash();
        pl.append("Version", version10).append("CmdId", request.getPartnerTransType().getType())
                .append("MerCustId", partner.getMerchantId()).append("UsrCustId", request.getUsrCustId())
                .append("ChkValue", checkValue);
        String htmlString = null;

        htmlString = WebClientUtil.autoSubmitHtmlForm(MSConstants.UTF8, request.getPartnerTransType().getText(),
                partner.getGateWayUrl(), pl.getParams(), "POST");
        logger.info(request.getPartnerTransType().getType() + "生成的表单内容为：\n" + htmlString);

        ResponseMessage response = new ResponseMessage();
        response.setOrderFormContent(htmlString);
        response.setRespCode(RespCodeConstants.CommonCode.TRANS_SUC);
        return response;
    }

    @SuppressWarnings("unchecked")
    @Override
    public ReconciliationResponseMsg reconciliation(ReconciliationRequestMsg request) {
        ReconciliationResponseMsg response = new ReconciliationResponseMsg();
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getBeginDate()).append(request.getEndDate()).append(request.getPageNum())
                .append(request.getPageSize()).append(request.getQueryTransType());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version10));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));// 商户客户号
        params.add(new BasicNameValuePair("BeginDate", request.getBeginDate()));
        params.add(new BasicNameValuePair("EndDate", request.getEndDate()));
        params.add(new BasicNameValuePair("PageNum", request.getPageNum()));
        params.add(new BasicNameValuePair("PageSize", request.getPageSize()));
        params.add(new BasicNameValuePair("QueryTransType", request.getQueryTransType()));
        params.add(new BasicNameValuePair("ChkValue", checkValue));

        String resultJsonString = httpRequest(params, partner.getGateWayUrl());
        Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(resultJsonString, HashMap.class);
        if (verifySign(paramMap, VERIFY_KEYS__RECONCILIATION)) {
            response = JsonUtils.createGson().create().fromJson(resultJsonString, ReconciliationResponseMsg.class);
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @Override
    @SuppressWarnings("unchecked")
    public TrfReconciliationResponseMsg trfReconciliation(TrfReconciliationRequestMsg request) {
        TrfReconciliationResponseMsg response = new TrfReconciliationResponseMsg();
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getBeginDate()).append(request.getEndDate()).append(request.getPageNum())
                .append(request.getPageSize());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version10));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));// 商户客户号
        params.add(new BasicNameValuePair("BeginDate", request.getBeginDate()));
        params.add(new BasicNameValuePair("EndDate", request.getEndDate()));
        params.add(new BasicNameValuePair("PageNum", request.getPageNum()));
        params.add(new BasicNameValuePair("PageSize", request.getPageSize()));
        params.add(new BasicNameValuePair("ChkValue", checkValue));

        String resultJsonString = httpRequest(params, partner.getGateWayUrl());
        Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(resultJsonString, HashMap.class);
        if (verifySign(paramMap, VERIFY_KEYS__TRFRECONCILIATION)) {
            response = JsonUtils.createGson().create().fromJson(resultJsonString, TrfReconciliationResponseMsg.class);
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @Override
    @SuppressWarnings("unchecked")
    public SaveReconciliationResponseMsg saveReconciliation(SaveReconciliationRequestMsg request) {
        SaveReconciliationResponseMsg response = new SaveReconciliationResponseMsg();
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getBeginDate()).append(request.getEndDate()).append(request.getPageNum())
                .append(request.getPageSize());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version10));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));// 商户客户号
        params.add(new BasicNameValuePair("BeginDate", request.getBeginDate()));
        params.add(new BasicNameValuePair("EndDate", request.getEndDate()));
        params.add(new BasicNameValuePair("PageNum", request.getPageNum()));
        params.add(new BasicNameValuePair("PageSize", request.getPageSize()));
        params.add(new BasicNameValuePair("ChkValue", checkValue));

        String resultJsonString = httpRequest(params, partner.getGateWayUrl());
        Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(resultJsonString, HashMap.class);
        if (verifySign(paramMap, VERIFY_KEYS__SAVERECONCILIATION)) {
            response = JsonUtils.createGson().create().fromJson(resultJsonString, SaveReconciliationResponseMsg.class);
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @Override
    @SuppressWarnings("unchecked")
    public DrawReconciliationResponseMsg drawReconciliation(DrawReconciliationRequestMsg request) {
        DrawReconciliationResponseMsg response = new DrawReconciliationResponseMsg();
        StringLinker sl = new StringLinker();
        sl.append(version20).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getBeginDate()).append(request.getEndDate()).append(request.getPageNum())
                .append(request.getPageSize());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Version", version20));
        params.add(new BasicNameValuePair("CmdId", request.getPartnerTransType().getType()));
        params.add(new BasicNameValuePair("MerCustId", partner.getMerchantId()));// 商户客户号
        params.add(new BasicNameValuePair("BeginDate", request.getBeginDate()));
        params.add(new BasicNameValuePair("EndDate", request.getEndDate()));
        params.add(new BasicNameValuePair("PageNum", request.getPageNum()));
        params.add(new BasicNameValuePair("PageSize", request.getPageSize()));
        params.add(new BasicNameValuePair("ChkValue", checkValue));

        String resultJsonString = httpRequest(params, partner.getGateWayUrl());
        Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(resultJsonString, HashMap.class);
        if (verifySign(paramMap, VERIFY_KEYS__CASHRECONCILIATION)) {
            response = JsonUtils.createGson().create().fromJson(resultJsonString, DrawReconciliationResponseMsg.class);
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }

    @Override
    public CreditAssignResponse packageCreditAssign(CreditAssignRequest request) {
        CreditAssignResponse response = new CreditAssignResponse();
        StringLinker sl = new StringLinker();
        sl.append(version10).append(request.getPartnerTransType().getType()).append(partner.getMerchantId())
                .append(request.getSellCustId()).append(request.getCreditAmt()).append(request.getCreditDealAmt())
                .append(JsonUtils.createGson().create().toJson(request.getBidDetails())).append(request.getFee())
                .append(JsonUtils.createGson().create().toJson(request.getDivDetails())).append(request.getBuyCustId())
                .append(request.getOrdId()).append(request.getOrdDate()).append(request.getBgRetUrl());

        String checkValue = keyTool.signMessage(sl.toString());// 签名

        ParamHash pl = new ParamHash();
        pl.append("Version", version10).append("CmdId", request.getPartnerTransType().getType())
                .append("MerCustId", partner.getMerchantId()).append("SellCustId", request.getSellCustId())
                .append("CreditAmt", request.getCreditAmt()).append("CreditDealAmt", request.getCreditDealAmt())
                .append("BidDetails", JsonUtils.createGson().create().toJson(request.getBidDetails()))
                .append("Fee", request.getFee())
                .append("DivDetails", JsonUtils.createGson().create().toJson(request.getDivDetails()))
                .append("BuyCustId", request.getBuyCustId()).append("OrdId", request.getOrdId())
                .append("OrdDate", request.getOrdDate()).append("BgRetUrl", request.getBgRetUrl())
                .append("ChkValue", checkValue);
        // System.out.println(pl.getParams().toString());
        String htmlString = null;
        htmlString = autoSubmitHtmlFormJSON(MSConstants.UTF8, request.getPartnerTransType().getText(),
                partner.getGateWayUrl(), pl.getParams(), "POST");
        logger.info(request.getPartnerTransType().getType() + "生成的表单内容为：\n" + htmlString);

        response.setOrderFormContent(htmlString);
        response.setRespCode(RespCodeConstants.CommonCode.TRANS_SUC);
        return response;
    }

    @Override
    public NotifyResponseMsg creditAssignNotify(NotifyRequestMsg request) {
        NotifyResponseMsg response = new NotifyResponseMsg();
        if (verifySign(request.getParameter(), VERIFY_KEYS_CREDITASSIGN)) {
            CreditAssignResponse creditAssignResponse = JsonUtils.createGson().create()
                    .fromJson(request.getParamString(), CreditAssignResponse.class);

            ServiceResult<String> result = serviceFactory.getAssignService().dealAssignResult(creditAssignResponse);
            if (result.getIsSuccess()) {
                response.setReturnNotifyParamValue(returnNotifyParamValuePre + creditAssignResponse.getOrdId());
                response.setReturnObject(result.getReturnValue());
            }
            response.setRespDesc(result.getMessage());
            response.setRespCode(result.getCode());
        } else {
            response.setRespCode(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRCODE_DIGESTERROR);
            response.setRespDesc(RespCodeConstants.CommonCode.TRANSMESSAGE_ERRMSG_DIGESTERROR);
        }
        return response;
    }
}